/*
 * main.cpp
 *
 *  Created on: Nov 28, 2009
 *      Author: tptfc
 */

#include "common/utils/StringUtils.h"
#include "image/api/ImageEntity.h"
#include "image/impl/ImageController.h"
#include "filter/impl/HighBoost.h"
#include "filter/impl/Roberts.h"
#include "filter/impl/Sobel.h"
#include "filter/impl/LowPass.h"
#include "filter/impl/Mediana.h"


#include <iostream>
#include <string>
#include <mpi.h>

using namespace std;

void executeHightBoost(string imagePath) {
	IImageController *controller = ImageController::getInstance();
	ImageEntity *image = controller->getImage(imagePath);

	IFilter *highBoost = new HighBoost(1);
	ImageEntity *highImage = highBoost->apply(image);
	string hight = "_hightBoost";
	hight.append(imagePath);
	controller->saveImage(imagePath,  hight, highImage);
	delete highBoost;
	delete highImage;
}

void executeRoberts(string imagePath) {
	IImageController *controller = ImageController::getInstance();
	ImageEntity *image = controller->getImage(imagePath);

	IFilter *roberts = new Roberts(60);
	ImageEntity *robertsImage = roberts->apply(image);
	string robertsOut = "_roberts";
	robertsOut.append(imagePath);
	controller->saveImage(imagePath, robertsOut, robertsImage);
	delete robertsImage;
	delete roberts;
}

void executeSobel(string imagePath) {
	IImageController *controller = ImageController::getInstance();
	ImageEntity *image = controller->getImage(imagePath);

	IFilter *sobel = new Sobel(60);
	ImageEntity *sobelImage = sobel->apply(image);
	string sobelOut = "_sobel";
	sobelOut.append(imagePath);
	controller->saveImage(imagePath, sobelOut, sobelImage);
	delete sobelImage;
	delete sobel;
}

void media(string imagePath) {
	IImageController *controller = ImageController::getInstance();
	ImageEntity *image = controller->getImage(imagePath);

	IFilter *lowPass = new LowPass();
	ImageEntity *lowImage = lowPass->apply(image);
	string lowOut = "_media";
	lowOut.append(imagePath);
	controller->saveImage(imagePath, lowOut, lowImage);
	delete lowImage;
	delete lowPass;
}

void mediana(string imagePath) {
	IImageController *controller = ImageController::getInstance();
	ImageEntity *image = controller->getImage(imagePath);

	IFilter *mediana = new Mediana();
	ImageEntity *medianaImage = mediana->apply(image);
	string medianaOut = "_mediana";
	medianaOut.append(imagePath);
	controller->saveImage(imagePath, medianaOut, medianaImage);
	delete medianaImage;
	delete mediana;
}

int main(int argc, char **argv) {
	int highBoostRank = 0;
	int robertsRank = 1;
	int sobelRank = 2;
	int lowPassRank = 3;
	int medianaRank = 4;

	string imagePath = argv[1];

	MPI_Init(&argc, &argv);
	int rank;
	MPI_Comm_rank ( MPI_COMM_WORLD, & rank);

	int proccess;
	MPI_Comm_size( MPI_COMM_WORLD, & proccess);


	if (proccess == 1) {
		highBoostRank = 0;
		robertsRank = 0;
		sobelRank = 0;
		lowPassRank = 0;
		medianaRank = 0;
	} else if (proccess == 2) {
		highBoostRank = 0;
		robertsRank = 0;
		sobelRank = 1;
		lowPassRank = 1;
		medianaRank = 1;
	} else if (proccess == 3) {
		highBoostRank = 0;
		robertsRank = 1;
		sobelRank = 1;
		lowPassRank = 2;
		medianaRank = 2;
	} else if (proccess == 4) {
		highBoostRank = 0;
		robertsRank = 1;
		sobelRank = 1;
		lowPassRank = 2;
		medianaRank = 3;
	}


	//	EXECUTE FILTERS
	if (rank == highBoostRank) {
		executeHightBoost(imagePath);
	}
	if (rank == robertsRank) {
		executeRoberts(imagePath);
	}
	if (rank == sobelRank) {
		executeSobel(imagePath);
	}
	if (rank == lowPassRank) {
		media(imagePath);
	}
	if (rank == medianaRank) {
		mediana(imagePath);
	}
	MPI_Finalize();
}
